package com.rightsidetech.http.aspect;


import com.alibaba.fastjson.JSON;
import com.rightsidetech.commom.base.ResponseData;
import com.rightsidetech.commom.enums.CodeIdEnum;
import com.rightsidetech.commom.exception.BizException;
import com.rightsidetech.commom.utils.StringUtil;
import com.rightsidetech.system.service.SysAgentInfoService;
import com.rightsidetech.system.service.SysRoleService;
import com.rightsidetech.system.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * @Description 鉴权
 * @Author yinj
 * @Date 2021-5-14 14:31:10
 * @Version 1.0
 */
@Aspect
@Component
@Slf4j
public class AuthAspect {

    @Resource
    private SysUserService sysUserService;
    @Resource
    private SysRoleService sysRoleService;
    @Resource
    private SysAgentInfoService sysAgentInfoService;

    @Before("execution(* com.rightsidetech.*.controller..*.*(..)) " +
            "&& @annotation(com.rightsidetech.http.aspect.Auth)")
    public void doAround(JoinPoint pjp) throws BizException {
        checkSign(pjp);
    }
    private void checkSign(JoinPoint pjp) throws BizException {
        HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();
        //String token = StringUtils.isEmpty(request.getHeader("token_admin")) ? request.getHeader("token_agentAdmin"):request.getHeader("token_admin");
        String adminToken = null;
        String agentToken = null;
        if (StringUtils.isEmpty(request.getHeader("token_admin"))){
            agentToken = request.getHeader("token_agentAdmin");
        }else {
            adminToken = request.getHeader("token_admin");
        }

        Long loginInfoId = null;
        if (!StringUtil.isNullorEmpty(adminToken)) {
            //用户id
            loginInfoId = sysUserService.sysUsercheckToken(adminToken);
        } else if (!StringUtils.isEmpty(agentToken)) {
            loginInfoId = sysAgentInfoService.sysUsercheckToken(agentToken);
        } else{
            //从请求参数获取token
            Object[] args = pjp.getArgs();
            if (args != null && args.length > 1) {
                if (StringUtil.isNullorEmpty(args[1])) {
                    throw new BizException(CodeIdEnum.Expired);
                }
                String token = args[1].toString();
                try {
                    if (StringUtil.isNullorEmpty(token)) {
                        throw new BizException(CodeIdEnum.Expired);
                    }
                    loginInfoId = sysUserService.sysUsercheckToken(token);
                    if (StringUtils.isEmpty(loginInfoId)){
                        loginInfoId = sysAgentInfoService.sysUsercheckToken(token);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    log.info("json解析错误, args={}",JSON.toJSONString(args[0]));
                }
            }

        }
        if (StringUtil.isNullorEmpty(loginInfoId)){
            throw new BizException(CodeIdEnum.Expired);
        }
        String requestURI = request.getRequestURI();
        //获取方法头上的注解
        Auth auth = ((MethodSignature) pjp.getSignature()).getMethod()
                .getAnnotation(Auth.class);
        //获取注解里面的值
        String biz=  auth.bizType();

        // TODO 获取菜单url
        String menuUrl = null;

        ResponseData<Boolean> resp = sysRoleService.checkAuth(loginInfoId, biz, requestURI, menuUrl);
        if (resp == null ||  !resp.getResData()){
            throw new BizException(CodeIdEnum.NO_JURISDICTION);
        }
        request.setAttribute("infoId",loginInfoId);
    }
}
